//*****************************************************************************
// JFab (http://code.google.com/p/jfab)
// Copyright (c) 2011-2012 JFab.org
// Admin jfab@jeffreythompson.net
//
// See the file "LICENSE.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//*****************************************************************************

package org.jfab.swingui;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.ImageIcon;

import org.apache.commons.lang3.StringUtils;

/**
 * Provides a GUI icon manager.
 */
public class IconManager
{
    /** Icon name. */
    private static final String ABOUT_MESSAGE_NAME = "aboutMessage";

    /** Icon name. */
    private static final String ABOUT_NAME = "about";

    /** Icon name. */
    private static final String ADD_NODE_NAME = "addNode";

    /** Icon name. */
    private static final String CLASS_NAME = "class";

    /** Icon name. */
    private static final String COLLAPSE_ALL_NAME = "collapseAll";

    /** Icon name. */
    private static final String CONSTRUCTOR_NAME = "constructor";

    /** Icon name. */
    private static final String ENUM_ITEM_NAME = "enumItem";

    /** Icon name. */
    private static final String ENUM_NAME = "enum";

    /** Icon name. */
    private static final String EXPAND_ALL_NAME = "expandAll";

    /** Icon name. */
    private static final String FIELD_NAME = "field";

    /** Icon name. */
    private static final String GENERATE_NAME = "generate";

    /** Icon name. */
    private static final String INITIALZATION_BLOCK_NAME = "initializationBlock";

    /** Icon name. */
    private static final String INTERFACE_NAME = "interface";

    /** Icon name. */
    private static final String METHOD_DECLARATION_NAME = "methodDeclaration";

    /** Icon name. */
    private static final String METHOD_NAME = "method";

    /** Name to alt text. */
    private static final Map<String, String> NAME_TO_ALT_TEXT = new HashMap<String, String>();

    /** Name to icon name. */
    private static final Map<String, String> NAME_TO_FILENAME = new HashMap<String, String>();

    /** Icon name. */
    private static final String NEW_NAME = "new";

    /** Icon name. */
    private static final String OPEN_NAME = "open";

    /** Icon name. */
    private static final String PARAMETER_NAME = "parameter";

    /** Icon name. */
    private static final String PROPERTY_NAME = "property";

    /** Icon name. */
    private static final String REMOVE_NODE_NAME = "removeNode";

    /** Icon name. */
    private static final String SAVE_AS_NAME = "saveAs";

    /** Icon name. */
    private static final String SAVE_NAME = "save";

    static
    {
        // Action icons.
        NAME_TO_ALT_TEXT.put(ABOUT_NAME, "About JFab UI");
        NAME_TO_ALT_TEXT.put(ADD_NODE_NAME, "Add");
        NAME_TO_ALT_TEXT.put(COLLAPSE_ALL_NAME, "Collapse All");
        NAME_TO_ALT_TEXT.put(EXPAND_ALL_NAME, "Expand All");
        NAME_TO_ALT_TEXT.put(GENERATE_NAME, "Generate...");
        NAME_TO_ALT_TEXT.put(NEW_NAME, "New...");
        NAME_TO_ALT_TEXT.put(OPEN_NAME, "Open...");
        NAME_TO_ALT_TEXT.put(REMOVE_NODE_NAME, "Remove");
        NAME_TO_ALT_TEXT.put(SAVE_NAME, "Save");
        NAME_TO_ALT_TEXT.put(SAVE_AS_NAME, "Save As...");

        // Tree icons.
        NAME_TO_ALT_TEXT.put(CLASS_NAME, "Class");
        NAME_TO_ALT_TEXT.put(CONSTRUCTOR_NAME, "Constructor");
        NAME_TO_ALT_TEXT.put(ENUM_NAME, "Enum");
        NAME_TO_ALT_TEXT.put(ENUM_ITEM_NAME, "EnumItem");
        NAME_TO_ALT_TEXT.put(FIELD_NAME, "Field");
        NAME_TO_ALT_TEXT.put(INITIALZATION_BLOCK_NAME, "Initialization Block");
        NAME_TO_ALT_TEXT.put(INTERFACE_NAME, "Interface");
        NAME_TO_ALT_TEXT.put(METHOD_NAME, "Method");
        NAME_TO_ALT_TEXT.put(METHOD_DECLARATION_NAME, "Method Declaration");
        NAME_TO_ALT_TEXT.put(PARAMETER_NAME, "Parameter");
        NAME_TO_ALT_TEXT.put(PROPERTY_NAME, "Property");

        // Other icons.
        NAME_TO_ALT_TEXT.put(ABOUT_MESSAGE_NAME, "JFab");
    }

    static
    {
        // Action icons.
        NAME_TO_FILENAME.put(ABOUT_NAME, "info.png");
        NAME_TO_FILENAME.put(ADD_NODE_NAME, "Plus16.png");
        NAME_TO_FILENAME.put(COLLAPSE_ALL_NAME, "UpArrow16.png");
        NAME_TO_FILENAME.put(EXPAND_ALL_NAME, "DownArrow16.png");
        NAME_TO_FILENAME.put(GENERATE_NAME, "process.png");
        NAME_TO_FILENAME.put(NEW_NAME, "page.png");
        NAME_TO_FILENAME.put(OPEN_NAME, "folder.png");
        NAME_TO_FILENAME.put(REMOVE_NODE_NAME, "Minus16.png");
        NAME_TO_FILENAME.put(SAVE_NAME, "save.png");

        // Tree icons.
        NAME_TO_FILENAME.put(CLASS_NAME, "Class16.png");
        NAME_TO_FILENAME.put(CONSTRUCTOR_NAME, "Constructor16.png");
        NAME_TO_FILENAME.put(ENUM_NAME, "Enum16.png");
        NAME_TO_FILENAME.put(ENUM_ITEM_NAME, "EnumItem16.png");
        NAME_TO_FILENAME.put(FIELD_NAME, "Field16.png");
        NAME_TO_FILENAME.put(INITIALZATION_BLOCK_NAME,
                "InitializationBlock16.png");
        NAME_TO_FILENAME.put(INTERFACE_NAME, "Interface16.png");
        NAME_TO_FILENAME.put(METHOD_NAME, "Method16.png");
        NAME_TO_FILENAME
                .put(METHOD_DECLARATION_NAME, "MethodDeclaration16.png");
        NAME_TO_FILENAME.put(PARAMETER_NAME, "Parameter16.png");
        NAME_TO_FILENAME.put(PROPERTY_NAME, "Property16.png");

        // Other icons.
        NAME_TO_FILENAME.put(ABOUT_MESSAGE_NAME, "Fabber2-64.gif");
    }

    /** Name to icon. */
    private final Map<String, Icon> _nameToIcon = new HashMap<String, Icon>();

    /**
     * @return the aboutIcon
     */
    public Icon getAboutIcon()
    {
        return getIcon(ABOUT_NAME);
    }

    /**
     * @return the aboutMessageIcon
     */
    public Icon getAboutMessageIcon()
    {
        return getIcon(ABOUT_MESSAGE_NAME);
    }

    /**
     * @return the addNodeIcon
     */
    public Icon getAddNodeIcon()
    {
        return getIcon(ADD_NODE_NAME);
    }

    /**
     * @return the classIcon
     */
    public Icon getClassIcon()
    {
        return getIcon(CLASS_NAME);
    }

    /**
     * @return the collapseAllIcon
     */
    public Icon getCollapseAllIcon()
    {
        return getIcon(COLLAPSE_ALL_NAME);
    }

    /**
     * @return the constructorIcon
     */
    public Icon getConstructorIcon()
    {
        return getIcon(CONSTRUCTOR_NAME);
    }

    /**
     * @return the enumIcon
     */
    public Icon getEnumIcon()
    {
        return getIcon(ENUM_NAME);
    }

    /**
     * @return the enumItemIcon
     */
    public Icon getEnumItemIcon()
    {
        return getIcon(ENUM_ITEM_NAME);
    }

    /**
     * @return the expandAllIcon
     */
    public Icon getExpandAllIcon()
    {
        return getIcon(EXPAND_ALL_NAME);
    }

    /**
     * @return the fieldIcon
     */
    public Icon getFieldIcon()
    {
        return getIcon(FIELD_NAME);
    }

    /**
     * @return the generateIcon
     */
    public Icon getGenerateIcon()
    {
        return getIcon(GENERATE_NAME);
    }

    /**
     * @param iconName Icon name.
     * 
     * @return an icon.
     */
    public Icon getIcon(final String iconName)
    {
        Icon answer = _nameToIcon.get(iconName);

        if (answer == null)
        {
            final String filename = NAME_TO_FILENAME.get(iconName);
            if (StringUtils.isNotEmpty(filename))
            {
                final String imageLocation = "images/" + filename;
                final String altText = NAME_TO_ALT_TEXT.get(iconName);

                answer = createImageIcon(imageLocation, altText);
                _nameToIcon.put(iconName, answer);
            }
        }

        return answer;
    }

    /**
     * @return the initializationBlockIcon
     */
    public Icon getInitializationBlockIcon()
    {
        return getIcon(INITIALZATION_BLOCK_NAME);
    }

    /**
     * @return the interfaceIcon
     */
    public Icon getInterfaceIcon()
    {
        return getIcon(INTERFACE_NAME);
    }

    /**
     * @return the methodIcon
     */
    public Icon getMethodDeclarationIcon()
    {
        return getIcon(METHOD_DECLARATION_NAME);
    }

    /**
     * @return the methodIcon
     */
    public Icon getMethodIcon()
    {
        return getIcon(METHOD_NAME);
    }

    /**
     * @return the newIcon
     */
    public Icon getNewIcon()
    {
        return getIcon(NEW_NAME);
    }

    /**
     * @return the openIcon
     */
    public Icon getOpenIcon()
    {
        return getIcon(OPEN_NAME);
    }

    /**
     * @return the parameterIcon
     */
    public Icon getParameterIcon()
    {
        return getIcon(PARAMETER_NAME);
    }

    /**
     * @return the propertyIcon
     */
    public Icon getPropertyIcon()
    {
        return getIcon(PROPERTY_NAME);
    }

    /**
     * @return the removeNodeIcon
     */
    public Icon getRemoveNodeIcon()
    {
        return getIcon(REMOVE_NODE_NAME);
    }

    /**
     * @return the saveAsIcon
     */
    public Icon getSaveAsIcon()
    {
        return getIcon(SAVE_AS_NAME);
    }

    /**
     * @return the saveIcon
     */
    public Icon getSaveIcon()
    {
        return getIcon(SAVE_NAME);
    }

    /**
     * @param imageLocation Image location.
     * @param altText Alternate text.
     * 
     * @return a new image icon.
     */
    private ImageIcon createImageIcon(final String imageLocation,
            final String altText)
    {
        ImageIcon answer = null;

        final URL imageUrl = getClass().getClassLoader().getResource(
                imageLocation);

        if (imageUrl != null)
        {
            answer = new ImageIcon(imageUrl, altText);
        }
        else
        {
            System.err.println("Resource not found: " + imageLocation);
        }

        return answer;
    }
}
